﻿
namespace SGTLightAccent.Web.Services
{
    using System;
    using System.Collections.Generic;
    using System.ComponentModel;
    using System.ComponentModel.DataAnnotations;
    using System.Data;
    using System.Linq;
    using System.ServiceModel.DomainServices.EntityFramework;
    using System.ServiceModel.DomainServices.Hosting;
    using System.ServiceModel.DomainServices.Server;
    using SGTLightAccent.Web.Models;


    // Implements application logic using the SGT_DB context.
    // TODO: Add your application logic to these methods or in additional methods.
    // TODO: Wire up authentication (Windows/ASP.NET Forms) and uncomment the following to disable anonymous access
    // Also consider adding roles to restrict access as appropriate.
    // [RequiresAuthentication]
    [EnableClientAccess()]
    public class SGTDomainService : LinqToEntitiesDomainService<SGT_DB>
    {

        // TODO:
        // Consider constraining the results of your query method.  If you need additional input you can
        // add parameters to this method or create additional query methods with different names.
        // To support paging you will need to add ordering to the 'aspnet_Roles' query.
        [RequiresRole("admin")]
        public IQueryable<aspnet_Roles> GetAspnet_Roles()
        {
            return this.ObjectContext.aspnet_Roles;
        }

        [RequiresRole("admin")]
        public void InsertAspnet_Roles(aspnet_Roles aspnet_Roles)
        {
            if ((aspnet_Roles.EntityState != EntityState.Detached))
            {
                this.ObjectContext.ObjectStateManager.ChangeObjectState(aspnet_Roles, EntityState.Added);
            }
            else
            {
                this.ObjectContext.aspnet_Roles.AddObject(aspnet_Roles);
            }
        }
        [RequiresRole("admin")]
        public void UpdateAspnet_Roles(aspnet_Roles currentaspnet_Roles)
        {
            this.ObjectContext.aspnet_Roles.AttachAsModified(currentaspnet_Roles, this.ChangeSet.GetOriginal(currentaspnet_Roles));
        }
        [RequiresRole("admin")]
        public void DeleteAspnet_Roles(aspnet_Roles aspnet_Roles)
        {
            if ((aspnet_Roles.EntityState == EntityState.Detached))
            {
                this.ObjectContext.aspnet_Roles.Attach(aspnet_Roles);
            }
            this.ObjectContext.aspnet_Roles.DeleteObject(aspnet_Roles);
        }

        // TODO:
        // Consider constraining the results of your query method.  If you need additional input you can
        // add parameters to this method or create additional query methods with different names.
        // To support paging you will need to add ordering to the 'aspnet_Users' query.
        [RequiresRole("admin")]
        public IQueryable<aspnet_Users> GetAspnet_Users()
        {
            return this.ObjectContext.aspnet_Users;
        }



        [RequiresRole("admin")]
        public void InsertAspnet_Users(aspnet_Users aspnet_Users)
        {
            if ((aspnet_Users.EntityState != EntityState.Detached))
            {
                this.ObjectContext.ObjectStateManager.ChangeObjectState(aspnet_Users, EntityState.Added);
            }
            else
            {
                this.ObjectContext.aspnet_Users.AddObject(aspnet_Users);
            }
        }
        [RequiresRole("admin")]
        public void UpdateAspnet_Users(aspnet_Users currentaspnet_Users)
        {
            this.ObjectContext.aspnet_Users.AttachAsModified(currentaspnet_Users, this.ChangeSet.GetOriginal(currentaspnet_Users));
        }
        [RequiresRole("admin")]
        public void DeleteAspnet_Users(aspnet_Users aspnet_Users)
        {
            if ((aspnet_Users.EntityState == EntityState.Detached))
            {
                this.ObjectContext.aspnet_Users.Attach(aspnet_Users);
            }
            this.ObjectContext.aspnet_Users.DeleteObject(aspnet_Users);
        }

        // TODO:
        // Consider constraining the results of your query method.  If you need additional input you can
        // add parameters to this method or create additional query methods with different names.
        // To support paging you will need to add ordering to the 'Barco' query.
        [RequiresRole("admin", "Operador")]
        public IQueryable<Barco> GetBarco()
        {
            return this.ObjectContext.Barco;
        }
        [RequiresAuthentication]
        public Barco GetBarcoID(int id)
        {
            var barco = (from b in ObjectContext.Barco
                         where b.id == id
                         select b).SingleOrDefault();
            return barco;
        }
        [RequiresRole("admin")]
        public void InsertBarco(Barco barco)
        {
            if ((barco.EntityState != EntityState.Detached))
            {
                this.ObjectContext.ObjectStateManager.ChangeObjectState(barco, EntityState.Added);
            }
            else
            {
                this.ObjectContext.Barco.AddObject(barco);
            }
        }
        [RequiresRole("admin")]
        public void UpdateBarco(Barco currentBarco)
        {
            this.ObjectContext.Barco.AttachAsModified(currentBarco, this.ChangeSet.GetOriginal(currentBarco));
        }
        [RequiresRole("admin")]
        public void DeleteBarco(Barco barco)
        {
            if ((barco.EntityState == EntityState.Detached))
            {
                this.ObjectContext.Barco.Attach(barco);
            }
            this.ObjectContext.Barco.DeleteObject(barco);
        }

        // TODO:
        // Consider constraining the results of your query method.  If you need additional input you can
        // add parameters to this method or create additional query methods with different names.
        // To support paging you will need to add ordering to the 'Bodega' query.
        [RequiresRole("admin","Operador")]
        public IQueryable<Bodega> GetBodega()
        {
            return this.ObjectContext.Bodega;
        }
        [RequiresAuthentication]
        public IQueryable<Bodega> GetBodegaByCarga(int idCarga)
        {
            var bodegas = from b in ObjectContext.Bodega
                          where b.Carga.Id == idCarga
                          select b;
            return bodegas;
        }
        [RequiresRole("admin")]
        public void InsertBodega(Bodega bodega)
        {
            if ((bodega.EntityState != EntityState.Detached))
            {
                this.ObjectContext.ObjectStateManager.ChangeObjectState(bodega, EntityState.Added);
            }
            else
            {
                this.ObjectContext.Bodega.AddObject(bodega);
            }
        }
        [RequiresRole("admin")]
        public void UpdateBodega(Bodega currentBodega)
        {
            this.ObjectContext.Bodega.AttachAsModified(currentBodega, this.ChangeSet.GetOriginal(currentBodega));
        }
        [RequiresRole("admin")]
        public void DeleteBodega(Bodega bodega)
        {
            if ((bodega.EntityState == EntityState.Detached))
            {
                this.ObjectContext.Bodega.Attach(bodega);
            }
            this.ObjectContext.Bodega.DeleteObject(bodega);
        }

        // TODO:
        // Consider constraining the results of your query method.  If you need additional input you can
        // add parameters to this method or create additional query methods with different names.
        // To support paging you will need to add ordering to the 'Carga' query.
        [RequiresRole("admin","operador")]
        public IQueryable<Carga> GetCarga()
        {
            return this.ObjectContext.Carga;
        }

        [RequiresAuthentication]
        public IQueryable<Carga> GetCargaFiltrada(string nomBarco, string cliente, DateTime fchIni, DateTime fchFin)
        {

            //Buscar producto en las bodegas
            AuthenticationService s = new AuthenticationService();//Aca filtro si es admin o cliente
            var admin = (from r in s.GetUser().Roles
                         where r.Equals("admin") || r.Equals("operador")
                         select r).SingleOrDefault();

            IQueryable<Carga> salida = null;
            if (admin != null)
            {



                var cargas = from c in ObjectContext.Carga
                             where (nomBarco == null || c.Barco.Nombre.Contains(nomBarco)) &&
                                    (cliente == null || c.Proveedor.Nombre.Contains(cliente)) &&

                                   c.Fecha_Ingreso >= fchIni &&
                                   c.Fecha_Salida <= fchFin
                             orderby c.Id descending
                             select c;
                salida = cargas;
            }
            else
            {
                var cargas = from c in ObjectContext.Carga
                             where (nomBarco == null || c.Barco.Nombre.Contains(nomBarco)) &&
                              (cliente == null || c.Proveedor.Nombre.Contains(cliente)) &&
                             c.Proveedor.Usuario_FK.Equals(s.GetUser().Name) &&
                                   c.Fecha_Ingreso >= fchIni &&
                                   c.Fecha_Salida <= fchFin
                             orderby c.Id descending
                             select c;
                salida = cargas;
            }
            return salida;
        }

        [RequiresAuthentication]
        public Carga GetUltimaCarga()
        {

            //Buscar producto en las bodegas
            AuthenticationService s = new AuthenticationService();//Aca filtro si es admin o cliente
            var admin = (from r in s.GetUser().Roles
                         where r.Equals("admin") || r.Equals("operador")
                         select r).SingleOrDefault();

            Carga salida = null;
            string usuario = s.GetUser().Name;


            if (admin != null)
            {



                var cargas = (from c in ObjectContext.Carga
                              orderby c.Id descending

                              select c).FirstOrDefault();
                salida = cargas;
            }
            else
            {
                var cargas = (from c in ObjectContext.Carga
                              where c.Proveedor.Usuario_FK.Equals(usuario)
                              orderby c.Id descending

                              select c).FirstOrDefault();

                salida = cargas;
            }
            return salida;
        }

        [RequiresAuthentication]
        public Carga GetCargaById(int id)
        {
            var carga = (from c in ObjectContext.Carga
                         where c.Id == id
                         select c).SingleOrDefault();
            return carga;
        }


        [RequiresRole("admin","operador")]
        public void InsertCarga(Carga carga)
        {
            if ((carga.EntityState != EntityState.Detached))
            {
                this.ObjectContext.ObjectStateManager.ChangeObjectState(carga, EntityState.Added);
            }
            else
            {
                this.ObjectContext.Carga.AddObject(carga);
            }
        }
        [RequiresRole("admin", "operador")]
        public void UpdateCarga(Carga currentCarga)
        {
            this.ObjectContext.Carga.AttachAsModified(currentCarga, this.ChangeSet.GetOriginal(currentCarga));
        }
        [RequiresRole("admin")]
        public void DeleteCarga(Carga carga)
        {
            if ((carga.EntityState == EntityState.Detached))
            {
                this.ObjectContext.Carga.Attach(carga);
            }
            this.ObjectContext.Carga.DeleteObject(carga);
        }

        // TODO:
        // Consider constraining the results of your query method.  If you need additional input you can
        // add parameters to this method or create additional query methods with different names.
        // To support paging you will need to add ordering to the 'Carga_Proveedor' query.


        // TODO:
        // Consider constraining the results of your query method.  If you need additional input you can
        // add parameters to this method or create additional query methods with different names.
        // To support paging you will need to add ordering to the 'Configuraciones' query.
        [RequiresRole("admin")]
        public IQueryable<Configuraciones> GetConfiguraciones()
        {
            return this.ObjectContext.Configuraciones;
        }
        [RequiresRole("admin")]
        public void InsertConfiguraciones(Configuraciones configuraciones)
        {
            if ((configuraciones.EntityState != EntityState.Detached))
            {
                this.ObjectContext.ObjectStateManager.ChangeObjectState(configuraciones, EntityState.Added);
            }
            else
            {
                this.ObjectContext.Configuraciones.AddObject(configuraciones);
            }
        }
        [RequiresRole("admin")]
        public void UpdateConfiguraciones(Configuraciones currentConfiguraciones)
        {
            this.ObjectContext.Configuraciones.AttachAsModified(currentConfiguraciones, this.ChangeSet.GetOriginal(currentConfiguraciones));
        }
        [RequiresRole("admin")]
        public void DeleteConfiguraciones(Configuraciones configuraciones)
        {
            if ((configuraciones.EntityState == EntityState.Detached))
            {
                this.ObjectContext.Configuraciones.Attach(configuraciones);
            }
            this.ObjectContext.Configuraciones.DeleteObject(configuraciones);
        }

        // TODO:
        // Consider constraining the results of your query method.  If you need additional input you can
        // add parameters to this method or create additional query methods with different names.
        // To support paging you will need to add ordering to the 'Deposito' query.
        [RequiresRole("admin", "operador")]
        public IQueryable<Deposito> GetDeposito()
        {
            return this.ObjectContext.Deposito;
        }
        [RequiresRole("admin")]
        public void InsertDeposito(Deposito deposito)
        {
            if ((deposito.EntityState != EntityState.Detached))
            {
                this.ObjectContext.ObjectStateManager.ChangeObjectState(deposito, EntityState.Added);
            }
            else
            {
                this.ObjectContext.Deposito.AddObject(deposito);
            }
        }
        [RequiresRole("admin")]
        public void UpdateDeposito(Deposito currentDeposito)
        {
            this.ObjectContext.Deposito.AttachAsModified(currentDeposito, this.ChangeSet.GetOriginal(currentDeposito));
        }
        [RequiresRole("admin")]
        public void DeleteDeposito(Deposito deposito)
        {
            if ((deposito.EntityState == EntityState.Detached))
            {
                this.ObjectContext.Deposito.Attach(deposito);
            }
            this.ObjectContext.Deposito.DeleteObject(deposito);
        }

        // TODO:
        // Consider constraining the results of your query method.  If you need additional input you can
        // add parameters to this method or create additional query methods with different names.
        // To support paging you will need to add ordering to the 'Mercaderia' query.
        [RequiresRole("admin")]
        public IQueryable<Mercaderia> GetMercaderia()
        {
            return this.ObjectContext.Mercaderia;
        }
        [RequiresRole("admin")]
        public void InsertMercaderia(Mercaderia mercaderia)
        {
            if ((mercaderia.EntityState != EntityState.Detached))
            {
                this.ObjectContext.ObjectStateManager.ChangeObjectState(mercaderia, EntityState.Added);
            }
            else
            {
                this.ObjectContext.Mercaderia.AddObject(mercaderia);
            }
        }
        [RequiresRole("admin")]
        public void UpdateMercaderia(Mercaderia currentMercaderia)
        {
            this.ObjectContext.Mercaderia.AttachAsModified(currentMercaderia, this.ChangeSet.GetOriginal(currentMercaderia));
        }
        [RequiresRole("admin")]
        public void DeleteMercaderia(Mercaderia mercaderia)
        {
            if ((mercaderia.EntityState == EntityState.Detached))
            {
                this.ObjectContext.Mercaderia.Attach(mercaderia);
            }
            try
            {
                this.ObjectContext.Mercaderia.DeleteObject(mercaderia);
            }
            catch (Exception ex)
            {
                string mensaje = ex.Message;
                if (ex.Message.Contains("DELETE"))
                    mensaje = "No es posible eliminar. El producto es utilizado en alguna descarga.";
                throw new Exception(mensaje);
            }
        }

        // TODO:
        // Consider constraining the results of your query method.  If you need additional input you can
        // add parameters to this method or create additional query methods with different names.
        // To support paging you will need to add ordering to the 'Proveedor' query.
         [RequiresRole("admin", "operador")]
        public IQueryable<Proveedor> GetProveedor()
        {
            return this.ObjectContext.Proveedor;
        }
        [RequiresRole("admin")]
        public void InsertProveedor(Proveedor proveedor)
        {
            if ((proveedor.EntityState != EntityState.Detached))
            {
                this.ObjectContext.ObjectStateManager.ChangeObjectState(proveedor, EntityState.Added);
            }
            else
            {
                this.ObjectContext.Proveedor.AddObject(proveedor);
            }
        }
        [RequiresRole("admin")]
        public void UpdateProveedor(Proveedor currentProveedor)
        {
            this.ObjectContext.Proveedor.AttachAsModified(currentProveedor, this.ChangeSet.GetOriginal(currentProveedor));
        }
        [RequiresRole("admin")]
        public void DeleteProveedor(Proveedor proveedor)
        {
            if ((proveedor.EntityState == EntityState.Detached))
            {
                this.ObjectContext.Proveedor.Attach(proveedor);
            }
            this.ObjectContext.Proveedor.DeleteObject(proveedor);
        }

        // TODO:
        // Consider constraining the results of your query method.  If you need additional input you can
        // add parameters to this method or create additional query methods with different names.
        // To support paging you will need to add ordering to the 'Remito_Barco' query.
        [RequiresRole("admin", "operador")]
        public IQueryable<Remito_Barco> GetRemito_Barco()
        {
            return this.ObjectContext.Remito_Barco;
        }
        [RequiresAuthentication]
        public IQueryable<Remito_Barco> GetRemito_Barco_Carga(int idCarga)
        {
            var remitos = from r in ObjectContext.Remito_Barco
                          where r.Carga_FK == idCarga
                          orderby r.Id descending

                          select r;
            return remitos;
        }
        [RequiresRole("admin", "operador")]
        public void InsertRemito_Barco(Remito_Barco remito_Barco)
        {
            if ((remito_Barco.EntityState != EntityState.Detached))
            {
                this.ObjectContext.ObjectStateManager.ChangeObjectState(remito_Barco, EntityState.Added);
            }
            else
            {
                this.ObjectContext.Remito_Barco.AddObject(remito_Barco);
            }
        }
        [RequiresRole("admin", "operador")]
        public void UpdateRemito_Barco(Remito_Barco currentRemito_Barco)
        {
            this.ObjectContext.Remito_Barco.AttachAsModified(currentRemito_Barco, this.ChangeSet.GetOriginal(currentRemito_Barco));
        }
        [RequiresRole("admin")]
        public void DeleteRemito_Barco(Remito_Barco remito_Barco)
        {
            if ((remito_Barco.EntityState == EntityState.Detached))
            {
                this.ObjectContext.Remito_Barco.Attach(remito_Barco);
            }
            this.ObjectContext.Remito_Barco.DeleteObject(remito_Barco);
        }
    }
}


